/**
 * JAVACC DEMO 1.0
 */
package com.apache.ius;

import com.apache.api.vo.ParamsVo;
import com.apache.api.vo.ResultEntity;
import com.apache.cache.util.Validator;
import com.apache.database.constant.SystemTools;
import com.apache.exception.BusinessException;
import com.apache.ius.function.FelFunction;
import com.apache.ius.plugin.IusPluginUtil;
import com.apache.tools.DateUtils;
import com.apache.tools.NumberUtils;
import com.apache.tools.StrUtil;
import com.greenpineyu.fel.FelEngine;
import com.greenpineyu.fel.FelEngineImpl;
import com.greenpineyu.fel.context.FelContext;
import org.apache.log4j.Logger;

import java.lang.reflect.Method;
import java.text.ParseException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * description:  表达式计算类
 * @author Administrator 创建时间：2016-12-8
 */
public class FelToolsUtil {
    private Logger log = Logger.getLogger(getClass());
    private static FelToolsUtil instance;
    private static FelEngine felEngine;
    private static FelContext felContext;
    //    private IDao iusPubDao;
    private FelToolsUtil() {
//        iusPubDao = (IDao) SpringContextLoader.getBean("iusPubDao");
    }
    public static FelToolsUtil getInstance() {
        if (null == instance) {
            instance = new FelToolsUtil();
        }
        felEngine= new FelEngineImpl();
        felContext = felEngine.getContext();
        return instance;
    }

    public void evl(ParamsVo vo) {
        String cateNo = String.valueOf(vo.getParams("cateNo"));//品种编号
        String saleId = String.valueOf(vo.getParams("saleId"));//发售id
        String proId = String.valueOf(vo.getParams("proId"));//产品id
        String constantType = String.valueOf(vo.getParams("constantType"));//功能类型/规则类型 主流程/受让方流程等
        String constantStatus = String.valueOf(vo.getParams("constantStatus"));//业务操作当前状态
        String constantResult = String.valueOf(vo.getParams("constantResult"));//定义规则返回结果集存储key
//        MethodParam params = new MethodParam("ByObjInfo", "", "",IusSqlTools.SPANCENAME);

        if (Validator.isNotNull(proId) || Validator.isNotNull(saleId)||  Validator.isNotNull(constantType)||  Validator.isNotNull(constantResult)) {

//            StringBuffer execSql = new StringBuffer(
//                    "select * from sys_rules_prod where constant_type='" + constantType
//                            + "' and constant_status='" + constantStatus + "' ");
//            if (Validator.isNotNull(saleId)) {
//                execSql.append("and sale_id='" + saleId + "' ");
//            }
//            if (Validator.isNotNull(proId)) {
//                execSql.append("and prod_id='" + proId + "' ");
//            }
//            if (Validator.isNotNull(cateNo)) {
//                execSql.append("and cate_no='" + cateNo + "' ");
//            }
//            execSql.append("order by order_no+0 asc");
//            params.setParams("datasource", "plateform");
//            params.setParams("dyncSql", execSql.toString());
//            List list = iusPubDao.select(params);
            Map<String, Object> whereMap = new HashMap<String,Object>();
            if(Validator.isNotNull(saleId)){
                whereMap.put("sysRulesProd.w_saleId", saleId);
            }
            if (Validator.isNotNull(proId)) {
                whereMap.put("sysRulesProd.w_proId", proId);
            }
            if (Validator.isNotNull(cateNo)) {
                whereMap.put("sysRulesProd.wi_cateNo", cateNo);
            }
            if (Validator.isNotNull(constantType)) {
                whereMap.put("sysRulesProd.wi_constantType", constantType);
            }
            if (Validator.isNotNull(constantStatus)) {
                whereMap.put("sysRulesProd.wi_constantStatus", constantStatus);
            }
            whereMap.put("orderBy", "sysRulesProd.rules_no,sysRulesProd.order_no+0");
            ResultEntity resS =  IusPluginUtil.getInstance().select("plateform", "list", "s_sysRulesProd", whereMap);
            if(resS==null || resS.getEntity()==null){
                return;
            }
            List list = (List)resS.getEntity();
            if (Validator.isEmpty(list))
                return;

            Map<String, Object> param = vo.getParams();
            log.info("request.param.data->"+param);
            for (int i = 0; i < list.size(); i++) {
                Map map = (Map) list.get(i);
                // numCalculate:数值公式计算类;numValidate:数值校验类;dateCalculate:日期公式计算类;dateValidate:日期校验类;custom:自定义方法类;
                String dealType = String.valueOf(map.get("dealType"));
                String formulaCal = String.valueOf(map.get("formulaCal"));
                String rulesNo = String.valueOf(map.get("rulesNo"));
                String rulesName = String.valueOf(map.get("rulesName"));
                String formulaName = String.valueOf(map.get("formulaName"));
                String paramNo = String.valueOf(map.get("paramNo"));
                String ruelsResFlag = String.valueOf(map.get("resFlag"));//控制计算结果是否返回结果

                param.put("rulesNo", rulesNo);
                param.put("paramNo", paramNo);
                param.put("formulaName", formulaName);
                if ("numCalculate".equals(dealType)) {//数字计算型
                    //trpPro.proAmount=trpPro.price*trpPub.itemNum+trpPro.priceTotal
                    String str[] = formulaCal.split("=");
                    //特殊处理计算结果存储至指定list中
                    if(!StrUtil.isNull(constantResult) && "T".equals(ruelsResFlag)){
                        addCalsResList(constantResult,vo,map,str[0]);
                    }else{
                        Object numCalVal = numCalculateForFel(rulesNo,formulaCal, param);
                        log.info("规则["+rulesNo+"]["+dealType+"]["+formulaName+"]["+formulaCal+"]->处理结果["+String.valueOf(numCalVal)+"]");
                        vo.setParams(str[0], numCalVal);
                    }
                } else if ("numValidate".equals(dealType)) {//数字判断型
                    numValidate(formulaCal, param);
                } else if ("dateValidate".equals(dealType)) {//日期判断型
                    dateValidate(formulaCal, param);
                } else if ("dateCalculate".equals(dealType)) {//日期计算型
                    String str[] = formulaCal.split("=");
                    Object rs = dateCalculate(formulaCal, param);
                    String keys[] = str[0].split(":");
                    if (keys.length > 1) {
                        vo.setParams(keys[1], rs);
                    } else {
                        vo.setParams(str[0], rs);
                    }
                } else if ("custom".equals(dealType)) {//自定义插件型
                    try {
                        log.info("规则["+rulesNo+"]["+dealType+"]["+formulaName+"]["+formulaCal+"]->[自定义插件]");
                        Class cls = Class.forName(formulaCal);
                        Method m = cls.getDeclaredMethod("run", new Class[] { ParamsVo.class });
                        m.invoke(cls.newInstance(), vo);
                    } catch (Exception e) {
                        e.printStackTrace();
                        throw new BusinessException(e.getCause().getMessage());
                    }
                } else if ("customFun".equals(dealType)) {//自定义静态函数
                    String str[] = formulaCal.split("=");
                    Object numCalVal = exeFormula(rulesNo,formulaCal, param);
                    log.info("规则["+rulesNo+"]["+dealType+"]["+formulaName+"]["+formulaCal+"]->处理结果["+String.valueOf(numCalVal)+"]");
                    vo.setParams(str[0], numCalVal);
                } else if ("datetext".equals(dealType)) {//日期或者文本赋值型
                    if(formulaCal.indexOf("=")>-1){
                        String str[] = formulaCal.split("=");
                        if (str.length > 0) {
                            vo.setParams(str[0], str[1]);
                            log.info("规则["+rulesNo+"]["+dealType+"]["+formulaName+"]["+formulaCal+"]->处理结果["+String.valueOf( vo.getParams(str[0]))+"]");
                        }
                    }
                }

            }

            printConstantResult_log(param); //打印返回结果

        }else{
            log.error("【constantType】【proId】【saleId】【constantResult】不能都为空！");
        }
    }

    //打印返回结果
    private void printConstantResult_log(Map<String, Object> param){
        String constantResultKeys = String.valueOf(param.get("constantResult"));
        if(param.containsKey(constantResultKeys)){
            List<Map> list = (List<Map>)param.get(constantResultKeys);
            log.info("-");
            log.info("<---- Rule execution is complete,return items,print to start. ---->");
            for (int i=0;i<list.size();i++){
                log.info((i+1)+"."+list.get(i));
            }
            log.info("<---- Rule execution is complete,return items,print to end.   ---->");
            log.info("-");
        }
    }

    /*
     特殊处理：返回计算结果和公式至[constantResult]，首先规则公司是开启了返回及（resFlag=T），本方法是二次筛选。
     注意param中的key命名规则=rules_custom_公式返回变量名称
     1）当无个性使用默认执行及返回结果时情况，无需定义key及准备值
     2）当某公式需根据业务选择性控制是否执行及返回结果时,需要自定义准备res参数=T
     3）当某公式需循环执行及返回结果多遍时,需要自定义准备list参数(其他公式可变因子参数、其他业务参数）
     4）调用触发的参数必须包含：constantResult
     */
    private void addCalsResList(String constantResult,ParamsVo vo,Map sysRulesProd,String calKey){
        Map<String, Object> param = vo.getParams();
        String sysRulesProd_constantType = String.valueOf(sysRulesProd.get("constantType"));
        String sysRulesProd_constantStatus = String.valueOf(sysRulesProd.get("constantStatus"));
        String formulaCal = String.valueOf(sysRulesProd.get("formulaCal"));
        String rulesNo = String.valueOf(sysRulesProd.get("rulesNo"));
        String rulesName = String.valueOf(sysRulesProd.get("rulesName"));
        String dealType = String.valueOf(sysRulesProd.get("dealType"));
        String formulaName = String.valueOf(sysRulesProd.get("formulaName"));

        List calsResList = new ArrayList<>();
        Object calResultObj = vo.getParams(constantResult);
        if(calResultObj!=null){
            calsResList = (List)calResultObj;
        }

        //判断业务上是否再次自定义了个性规则（循环此公式多变，自定义是否返回等）
        String rules_custom_key = "rules_custom_"+calKey;
        Object rules_custom_obj = vo.getParams(rules_custom_key);
        Map<String,Object> rules_custom_map = new HashMap<String,Object>();
        if(rules_custom_obj!=null) rules_custom_map = (Map)rules_custom_obj;
        String rules_custom_res_flag = StrUtil.doNull(String.valueOf(rules_custom_map.get("res")), "T");
        Object loopObj = rules_custom_map.get("list");
        List<Map> rules_custom_loop =  new ArrayList<Map>();
        if(loopObj!=null) rules_custom_loop = (List<Map>)loopObj;

        Map<String,Object> calResultMap = new HashMap<String,Object>();

        if("T".equalsIgnoreCase(rules_custom_res_flag)){
            if(rules_custom_loop.size()>0){
                //出现多种需要循环时
                for (int j=0;j<rules_custom_loop.size();j++){
                    calResultMap = new HashMap<String,Object>();
                    Map customMap = rules_custom_loop.get(j);
//                    String itemKey = String.valueOf(customMap.get("key"));
                    param.putAll(customMap);
                    Object numCalVal = numCalculateForFel(rulesNo,formulaCal, param);
                    log.info("规则["+rulesNo+"]["+dealType+"]["+formulaName+"]["+formulaCal+"]->处理结果["+String.valueOf(numCalVal)+"]");
                    calResultMap.put("constantType",sysRulesProd_constantType);
                    calResultMap.put("constantStatus",sysRulesProd_constantStatus);
                    calResultMap.put("rulesName",rulesName);
                    calResultMap.put("calculateKey",calKey);
                    calResultMap.put("calculateVal",numCalVal);
                    calResultMap.put("calculate",formulaCal);
                    calResultMap.put("otherParam",customMap.get("otherParam"));
                    calsResList.add(calResultMap);
                }
            }else{
                //单一未定义默认情况下
                Object numCalVal = numCalculateForFel(rulesNo,formulaCal, param);
                log.info("规则["+rulesNo+"]["+dealType+"]["+formulaName+"]["+formulaCal+"]->处理结果["+String.valueOf(numCalVal)+"]");
                calResultMap.put("constantType",sysRulesProd_constantType);
                calResultMap.put("constantStatus",sysRulesProd_constantStatus);
                calResultMap.put("rulesName",rulesName);
                calResultMap.put("calculateKey",calKey);
                calResultMap.put("calculateVal",numCalVal);
                calResultMap.put("calculate",formulaCal);
                calResultMap.put("otherParam","");
                calsResList.add(calResultMap);
            }

            vo.setParams(constantResult,calsResList);
        }
    }

    public void calculate(ParamsVo vo) {

    }

    public boolean compare(ParamsVo vo) {
        return false;
    }

    /**
     * description:  数值公式计算类
     */
    public Object numCalculateForFel(String rulesNo,String formulaCal, Map<String, Object> param) {
        formulaCal = formulaCal.replace("==", "###");
        formulaCal = formulaCal.replace("<=", "#lteq#");
        formulaCal = formulaCal.replace(">=", "#gteq#");
        formulaCal = formulaCal.replace("[[", "'").replace("]]", "'");
        String str[] = formulaCal.split("=");
        String eval = str[1];
        StringBuffer keyssb = new StringBuffer("");
        for (String key : param.keySet()) {
            if (str[1].indexOf(key)!=-1) {
                String val = String.valueOf(param.get(key));
                keyssb.append("["+key+"="+val+"]");
                if (isNumeric(val)) {
                    felContext.set(key.replace(".", "_"), Double.valueOf(val));
                } else {
                    felContext.set(key.replace(".", "_"), val);
                }

                eval = eval.replace(key, key.replace(".", "_"));
                //str[1] = str[1].replace(key, String.valueOf(param.get(key)));
            }
        }
        if(keyssb.length()>0){
            log.info("规则["+rulesNo+"]->variables required by formulas："+keyssb.toString());
        }
        eval = eval.replace("###", "==").replace("#lteq#","<=").replace("#gteq#",">=" );
        Object result = null;
        try {
            result = felEngine.eval(eval);
        } catch (Exception ew) {
            log.error("规则["+rulesNo+"]->【【异常错误】】[exception message->"+ew.getMessage()+"][可能是变量缺失或者类型不符导致异常！！！]");
//            ew.printStackTrace();
        }
        if(result!=null){
            String res = NumberUtils.format(Double.valueOf(String.valueOf(result)), 2, false);
            return res;
        }else{
            return "";
        }

    }

    /**
     * description:  数值公式校验类
     */
    private boolean numValidate(String formulaCal, Map<String, Object> param) {
        for (String key : param.keySet()) {
            if (formulaCal.indexOf(key) != -1) {
                felContext.set(key.replace(".", "_"), Double.valueOf(String.valueOf(param.get(key))));
                formulaCal = formulaCal.replace(key, key.replace(".", "_"));
                //formulaCal = formulaCal.replace(key, String.valueOf(param.get(key)));
            }
        }

        if (formulaCal.indexOf('>') == -1 && formulaCal.indexOf('<') == -1
                && formulaCal.indexOf("==") == -1) {
            String compareStr[] = formulaCal.split("=");
            Object result = felEngine.eval(compareStr[1].replace(".", "_"));
            //如果不是整数，则默认保留小数点后两位。
            if (String.valueOf(result).contains(".")) {
                result = String.format("%.2f", result);
            }
            Object paramResult = param.get(compareStr[0]);//页面中传过来的计算结果
            felContext.set("result", result);
            felContext.set("paramResult", paramResult);
            //对比两个值是否相等
            if ("true".equalsIgnoreCase(String.valueOf(felEngine.eval("result==paramResult")))) {
                return true;
            } else {
                log.info("----"+param.get("formulaName") + "[" + param.get("rulesNo") + "][" + formulaCal
                        + "]-公式校验失败！");
                throw new BusinessException(
                        param.get("rulesNo") + "|" + param.get("formulaName") + ",数据验证失败！");
            }

        }
        Object result = felEngine.eval(formulaCal);
        log.info("----[numValidate][" + param.get("formulaName") + "][" + formulaCal + "]->处理结果："
                + result);
        if (!"true".equalsIgnoreCase(String.valueOf(result))) {
            log.info(param.get("formulaName") + "[" + param.get("rulesNo") + "][" + formulaCal
                    + "]-公式校验失败！");
            throw new BusinessException(
                    param.get("rulesNo") + "|" + param.get("formulaName") + "|数据验证失败！|" + param
                            .get("paramNo"));
        }
        return true;
    }

    /**
     * 正常的普通公式执行
     */
    public Object exeFormula(String rulesNo,String formulaCal, Map<String, Object> param) {
        String str[] = formulaCal.split("=");
        String eval = str[1];
        StringBuffer keyssb = new StringBuffer("");
        for (String key : param.keySet()) {
            if (str[1].indexOf(key) != -1) {
                String val = String.valueOf(param.get(key));
                keyssb.append("["+key+"="+val+"]");
                felContext.set(key, val);
            }
        }
        if(keyssb.length()>0){
            log.info("规则["+rulesNo+"]->variables required by formulas："+keyssb.toString());
        }else{
            log.error("规则["+rulesNo+"]->this function required param is all empty");
        }
        Object result = null;
        try {
            result = felEngine.eval(eval);
        } catch (Exception ew) {
            log.error(ew.getMessage());
//            ew.printStackTrace();
        }
        if(result!=null){
            return result;
        }else{
            return "";
        }
    }

    private boolean dateValidate(String formulaCal, Map<String, Object> param) {
        String expPrefix = formulaCal;
        String keys[] = formulaCal.split(":");
        String enumKey = "dateCompare";
        if (keys.length > 1) {
            enumKey = keys[0];
            expPrefix = keys[1];
        }
        for (String key : param.keySet()) {
            if (expPrefix.indexOf(key) != -1) {
                expPrefix = expPrefix.replace(key, String.valueOf(param.get(key)));
            }
        }
        String exp = "";
        if (expPrefix.indexOf("certEndTime") != -1) {
            felEngine.addFun(FelFunction.getInstance().dateValidate());
            exp = "dateValidate('dateCompare','" + expPrefix + "')";
        }
        Object eval = felEngine.eval(exp);
        if (Validator.isNull(String.valueOf(eval))) {
            log.info(param.get("formulaName") + "[" + param.get("rulesNo") + "][" + formulaCal
                    + "]-公式校验失败！");
            throw new BusinessException(
                    param.get("rulesNo") + "|" + param.get("formulaName") + ",数据验证失败！");
        }
        eval = felEngine.eval(String.valueOf(eval));
        log.info("----[dateValidate][" + param.get("formulaName") + "][" + eval + "]->处理结果：" + eval);
        if (!"true".equalsIgnoreCase(String.valueOf(eval))) {
            log.info(param.get("formulaName") + "[" + param.get("rulesNo") + "][" + formulaCal
                    + "]-公式校验失败！");
            throw new BusinessException(
                    param.get("rulesNo") + "|" + param.get("formulaName") + ",数据验证失败！");
        }
        return true;
    }

    /**
     * description:  日期 公式计算类
     */
    private Object dateCalculate(String formulaCal, Map<String, Object> param) {
        String str[] = formulaCal.split("=");
        String expPrefix = str[1];
        //如果含有sysdate，则将sysdate替换为当前时间。
        String keys[] = str[0].split(":");
        String enumKey = "sumDate";
        if (keys.length > 1) {
            enumKey = keys[0];
        }
        if (expPrefix.indexOf("sysdate") != -1) {
            expPrefix = expPrefix.replace("sysdate", DateUtils.getToday());
        }
        if (expPrefix.indexOf("systime") != -1) {
            expPrefix = expPrefix.replace("systime", DateUtils.Now.fmt_HHmmss());
        }
        if (expPrefix.indexOf("sysDateTime") != -1) {
            expPrefix = expPrefix.replace("sysDateTime", DateUtils.Now.fmt_yyyyMMdd_HHmmss());

        }
        //		if (formulaCal.indexOf("sysLongdate") > 0) {
        //			return System.currentTimeMillis() + "";
        //		}
        //trs.orderDate = sysdate
        for (String key : param.keySet()) {
            if (expPrefix.indexOf(key) != -1) {
                expPrefix = expPrefix.replace(key, String.valueOf(param.get(key)));
            }
        }
        String exp = "";
        felEngine.addFun(FelFunction.getInstance().dateCalculate());
        //		String args[] = new String[2];
        //		args[0]=enumKey;

        exp = "dateCalculate('" + enumKey + "','" + expPrefix + "')";
        Object eval = felEngine.eval(exp);
        log.info("----[dateCalculate][" + param.get("formulaName") + "][" + exp + "]->处理结果：" + eval);
        return eval;
    }

    private String densgerSql(ParamsVo vo, String prefix) {
        String sortCode = "";
        String tab = upperCharToUnderLine(prefix);
        if (tab.indexOf('_') == -1)
            return "";
        sortCode = tab.substring(tab.indexOf('_') + 1);
        String key = sortCode + "_tableAttr";
        String content = String
                .valueOf(SystemTools.getInstance().getCache("").getCacheObjectByKey(key));
        if (Validator.isNotNull(content))
            return content;
        return "1;*;info_id;" + tab;
    }

    /**
     * description:  将类属性改成数据字段名
     */
    private String upperCharToUnderLine(String param) {
        Pattern p = Pattern.compile("[A-Z]");
        if (param == null || param.equals("")) {
            return "";
        }
        StringBuilder builder = new StringBuilder(param);
        Matcher mc = p.matcher(param);
        int i = 0;
        while (mc.find()) {
            builder.replace(mc.start() + i, mc.end() + i, "_" + mc.group().toLowerCase());
            i++;
        }
        if ('_' == builder.charAt(0)) {
            builder.deleteCharAt(0);
        }
        return builder.toString();
    }

    private boolean isNumeric(String str) {
        Pattern pattern = Pattern.compile("(^[0-9]+(.[0-9]{1,6})?$)|(^\\-[0-9]+(.[0-9]{1,6})?$)");
        return pattern.matcher(str).matches();
    }

    private boolean isDate(String str) {
        Pattern pattern = Pattern.compile(
                "(\\d{4}-\\d{1,2}-\\d{1,2})|(\\d{4}-\\d{1,2}-\\d{1,2}\\s\\d{2}:\\d{2}:\\d{2})");
        return pattern.matcher(str).matches();
    }

    public static void main(String[] args) {
        FelEngine fel = new FelEngineImpl();
        FelContext ctx = fel.getContext();
        ctx.set("totalMoney", 100);
        ctx.set("buyFee", 10);
        ctx.set("sellFee", 20);
        ctx.set("flag", "buy");
        System.out.println("普通运算->"+fel.eval("totalMoney*buyFee+sellFee"));
        System.out.println("三目运算->"+fel.eval("(flag=='buy')?(totalMoney+buyFee):(sellFee)"));


        /**
         * 复杂判断计算：例如如下需求
         *（1）减损<=5万，劳务费=减损*6%;
         * (2)减损>5万且减损<=10万，劳务费=5万*6%+（减损-5万）*8%；
         * (3）减损>10万，劳务费==5万*6%+5万*8%+（减损-10万）*10%
         */
        ctx.set("price", 40000);
        String cals = "(price<=50000)?(price*0.06):((price>50000&&price<=100000)?(50000*0.06+(price-50000)*0.08):(50000*0.06+50000*0.08+(price-100000)*0.1))";
        System.out.println("40000判断&&计算情况1->"+fel.eval(cals));
        ctx.set("price", 80000);
        System.out.println("80000判断&&计算情况2->"+fel.eval(cals));
        ctx.set("price", 120000);
        System.out.println("120000判断&&计算情况3->"+fel.eval(cals));

        int[] intArray = {1,2,3};
        ctx.set("intArray", intArray);
        System.out.println("访问数组->"+fel.eval("intArray[1]"));

        Map<String,String> m = new HashMap<String, String>();
        m.put("user1", "user111");
        m.put("user2", "user222");
        ctx.set("userMap", m);
        System.out.println("访问Map指定key对应value->"+fel.eval("userMap.user1"));

        ctx.set("x", 2);
        ctx.set("y", 3);
        cals = "$('Math').pow(x,y)";
        System.out.println("调用静态方法Math.pow(x的y次方)->"+fel.eval(cals));

        try {
            ctx.set("nowDate",DateUtils.parse("2019-09-05"));
            ctx.set("day",3);
            cals = "$('com.apache.tools.DateUtils').beforeNDays(nowDate,day)";//等价 DateUtils.beforeNDays(now,3)
            Date befDate = (Date)fel.eval(cals);
            System.out.println("调用自定义类的方法->"+DateUtils.format(befDate, DateUtils.FmtStr.yyyyMMdd.toString()));
        } catch (ParseException e) {
            e.printStackTrace();
        }
//        Map<String,Object> param = new HashMap<>();
//        param.put("provinceCode", "11");
//        param.put("cityCode","22");
//        String fcal = "coeffType=$('com.common.CommonUtils').getCoeffType(provinceCode,cityCode)";
//        Object resutl = FelToolsUtil.getInstance().exeFormula("",fcal,param);
//        System.out.println(fcal+"->"+resutl+"->"+param);
    }

}
